<template>
  <div class="app-container">
    <el-form :model="queryForm" ref="queryFormRef" :inline="true">
      <el-form-item prop="title" label="菜单名称">
        <el-input v-model="queryForm.title" placeholder="请输入菜单名称" @press-enter="handleQuery" />
      </el-form-item>
      <el-form-item prop="visible" label="状态">
        <el-select v-model="queryForm.visible" placeholder="请选择菜单状态">
          <el-option value="1">显示</el-option>
          <el-option value="0">隐藏</el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-space>
          <el-button type="primary" @click="handleQuery">搜索</el-button>
          <el-button @click="resetQueryForm">重置</el-button>
        </el-space>
      </el-form-item>
    </el-form>

    <el-divider />

    <!-- 动作 -->
    <div class="action">
      <el-space>
        <el-button type="primary" @click="handleAddMenu()">新增菜单</el-button>
      </el-space>
    </div>

    <el-table :data="tableData" row-key="menuId" v-loading="uiConf.isLoading" :key="uiConf.isLoading" table-layout="auto">
      <el-table-column label="菜单名称" prop="title"></el-table-column>
      <el-table-column label="图标" prop="icon">
        <template #default="scope">
          <el-icon v-if="scope.row.icon">
            <component :is="scope.row.icon" />
          </el-icon>
        </template>
      </el-table-column>
      <el-table-column label="路由地址" prop="path"></el-table-column>
      <el-table-column label="组件地址" prop="component"></el-table-column>
      <el-table-column label="排序" prop="sort"></el-table-column>
      <el-table-column label="类型" prop="menuType">
        <template #default="scope">
          <el-tag type="" v-if="scope.row.menuType === 'M'">目录</el-tag>
          <el-tag type="warning" v-else-if="scope.row.menuType === 'C'">菜单</el-tag>
          <el-tag type="info" v-else-if="scope.row.menuType === 'F'">按钮</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="是否外联" prop="isFrame">
        <template #default="scope">
          <el-tag v-if="scope.row.isFrame == '1'" type="">内部</el-tag>
          <el-tag v-else type="danger">外部</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="显示状态" prop="visible">
        <template #default="scope">
          <el-tag v-if="scope.row.visible == '0'" type="">显示</el-tag>
          <el-tag v-else type="danger">隐藏</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="操作" prop="action">
        <template #default="scope">
          <el-button v-has="'admin:sysMenu:add'" text type="primary"
            @click="handleAddMenu(scope.row.menuId)">新增</el-button>
          <el-button v-has="'admin:sysMenu:edit'" text type="primary" @click="handleUpdate(scope.row)">修改</el-button>
          <el-button v-has="'admin:sysMenu:remove'" text type="primary" @click="
              () => {
                deleteVisible = true;
                deleteData = [scope.row.menuId];
              }
            ">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-pagination :page-size="10" v-model="currentPage" layout="prev, pager, next" :total="pager.count"
      @current-change="reloadCurrent(pager)" />

    <!-- 菜单管理新增与提交弹窗 -->
    <el-dialog v-model="modalVisible" :title="modalTitle" title-align="start" :width="800" modal-class="menu-modal"
      @close="resetModalForm">
      <el-form :model="modalForm" :rules="modalRules" ref="modalFormRef" auto-label-width label-align="left">
        <el-form-item prop="menuType" label="菜单类型">
          <el-radio-group v-model="modalForm.menuType">
            <el-radio label="M">目录</el-radio>
            <el-radio label="C">菜单</el-radio>
            <el-radio label="F">按钮</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-row :gutter="24">
          <el-col :span="12">
            <el-form-item prop="parentId" label="上级菜单">
              <el-tree-select v-model="modalForm.parentId" :data="tableData" :props="{ label: 'title',value:'menuId' }"
                check-strictly placeholder="请选择上级菜单">
              </el-tree-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item prop="title" label="菜单标题">
              <el-input v-model="modalForm.title" placeholder="请输入菜单标题" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="24">
          <el-col :span="12">
            <el-form-item prop="icon" label="菜单图标">
              <el-select v-model="modalForm.icon" filterable placeholder="请选择菜单图标">
                <el-option v-for="icon in parseIconName()" :key="icon.value" :value="icon.value" :label="icon.value">
                  <el-icon>
                    <component :is="icon.value" />
                  </el-icon>
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item prop="sort" label="显示排序">
              <el-input-number v-model="modalForm.sort" mode="button" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="24">
          <el-col :span="12" v-if="modalForm.menuType !== 'F'">
            <el-form-item prop="menuName" label="路由名称">
              <el-input v-model="modalForm.menuName" placeholder="请输入路由名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="modalForm.menuType !== 'F'">
            <el-form-item prop="component" label="组件名称">
              <el-input v-model="modalForm.component" placeholder="请输入组件名称" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="24">
          <el-col :span="12" v-if="modalForm.menuType !== 'F'">
            <el-form-item prop="path" label="路由地址">
              <el-input v-model="modalForm.path" placeholder="请输入路由地址" />
            </el-form-item>
          </el-col>
          <el-col :span="12" v-if="modalForm.menuType === 'C' || modalForm.menuType === 'F'">
            <el-form-item prop="permission" label="权限标识">
              <el-input v-model="modalForm.permission" placeholder="请输入权限标识" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item prop="isFrame" label="是否外链" v-if="modalForm.menuType !== 'F'">
          <el-radio-group v-model="modalForm.isFrame">
            <el-radio label="0">是</el-radio>
            <el-radio label="1">否</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item prop="visible" label="菜单状态" v-if="modalForm.menuType !== 'F'">
          <el-radio-group v-model="modalForm.visible">
            <el-radio label="0">显示</el-radio>
            <el-radio label="1">隐藏</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item prop="apis" label="API权限" v-if="modalForm.menuType !== 'M'">
          <el-transfer v-model:model-value="modalForm.apis" :data="transferData" :title="['未授权', '已授权']" show-search />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-row justify="end">
          <el-button @click="modalFormRef.resetFields();modalVisible=false;">取消</el-button>
          <el-button type="primary" @click="handleSubmit">确认</el-button>
        </el-row>
      </template>
    </el-dialog>

    <!-- Akiraka 20230210 删除与批量删除 开始 -->
    <DeleteModal
      :data="deleteData"
      :visible="deleteVisible"
      :apiDelete="removeMenu"
      @deleteVisibleChange="() => (deleteVisible = false)"
    />
    <!-- Akiraka 20230210 删除与批量删除 结束 -->
  </div>
</template>

<script setup>
import {
  onMounted,
  reactive,
  ref,
  getCurrentInstance,
  computed,
  watch,
  watchEffect,
} from "vue";
import { getMenu } from "@/api/admin/menu";
import { getSysApi } from "@/api/admin/sys-api";
import {
  addMenu,
  removeMenu,
  updateMenu,
  getMenuDetails,
} from "@/api/admin/menu";
import * as ElementPlusIconsVue from "@element-plus/icons-vue";
// Akiraka 20230210 删除数据
const deleteData = ref([]);
// Akiraka 20230210 删除对话框
const deleteVisible = ref(false);
// Akiraka 20230210 监听删除事件
const queryFormRef = ref(null);
const modalFormRef = ref(null);

watch(
  () => deleteVisible.value,
  (value) => {
    if (value == false) {
      getSysMenuInfo(pager);
    }
  }
);

const { proxy } = getCurrentInstance();

const { queryForm, handleQuery } = useQueryData();
// 默认页码
const currentPage = ref(1);
let uiConf = {
  isLoading: false,
};

// 表格分页
const pager = {
  count: 0,
  current: 1,
  pageSize: 10,
};

// QueryModel
function useQueryData() {
  // 表单查询
  const queryForm = reactive({});
  const handleQuery = () => {
    getSysMenuInfo(queryForm);
  };

  return {
    queryForm,
    handleQuery,
  };
}

// 默认表单
const modalForm = reactive({
  menuType: "M",
  sort: 0,
  isFrame: "1",
  visible: "0",
});

// 表单校验
const modalRules = {
  title: [{ required: true, message: "请输入菜单名称" }],
  path: [{ required: true, message: "请输入菜单路由地址" }],
  component: [
    { required: true, message: "请输入菜单路由地址" },
    // { pattern: /^[\/el-Zel-z.-.()*]+$/, trigger: 'blur', message: '校验规则:  只允许输入字母 el-z 或大写 el-Z 与 -'}
  ],
};

// 监听事件 20220715
watchEffect(() => {
  // 当菜单类型为目录时组件地址则为 Layout
  if (modalForm.menuType == "M") {
    modalForm.component = "Layout";
  } else {
    // 当菜单类型设置为菜单时 如果为 Layout 则为空
    if (modalForm.component == "Layout") {
      modalForm.component = "";
      // 当菜单类型设置为菜单时 编辑页面显示正常内容
    } else {
      modalForm.component = modalForm.component;
    }
  }
});

const tableData = ref([]);

// Transfer Data
const transferData = ref([]);

// Modal
const modalVisible = ref(false);
const modalTitle = ref("默认标题");
let iconNameList = [];


// 创建新菜单
const handleAddMenu = (parentId = null) => {
  modalVisible.value = true;
  modalTitle.value = "新增菜单";
  if (parentId) modalForm.parentId = parentId;
  getSysMenuInfo();
};

// TreeSearchFilter

// 修改菜单
const handleUpdate = async (record) => {
  const res = await getMenuDetails(record.menuId);
  Object.assign(modalForm, res.data);

  modalTitle.value = "修改菜单";
  modalVisible.value = true;
};

const resetQueryForm = () => {
  queryFormRef.value.resetFields();
  handleQuery();
};

const resetModalForm = () => {
  modalFormRef.value.resetFields();
  modalForm.menuId = null;
  modalVisible.value = false;
};

const reloadCurrent = (pageQ) => {
  getSysMenuInfo(pageQ)
};

// handleSubmit 新增与修改按钮方法 20220713
const handleSubmit = (done) => {
  modalFormRef.value
    .validate(async (valid) => {
      if (valid) {
        if (!modalForm.menuId) {
          const { success } = await addMenu(modalForm);
          if (success) proxy.$message.success("新增成功");
        } else {
          const { success } = await updateMenu(modalForm, modalForm.menuId);
          if (success) proxy.$message.success("修改成功");
        }
        getSysMenuInfo(pager);
        done(true);
      } else {
        proxy.$message.error("表单校验失败");
        done(false);
      }
    })
    .then((isdone) => {
      if (isdone) resetModalForm();
    });
};

// 获取菜单信息
const getSysMenuInfo = async (params = {}) => {
  uiConf.isLoading = true;
  const { code, data, msg } = await getMenu(params);
  uiConf.isLoading = false;
  if (code == 200) {
    tableData.value = data;
  } else {
    proxy.$message.error(msg);
  }
};

// 获取API接口信息
const getSysApiInfo = async () => {
  const { code, data, msg } = await getSysApi({ pageSize: 10000, type: "BUS" });
  if (code == 200) {
    transferData.value = data.list.map((item) => {
      return { value: item.id, label: item.title };
    });
  } else {
    proxy.$message.error(msg);
  }
};

// 转换Icon Object 为 list
const parseIconName = () => {
  if (iconNameList.length != 0) return iconNameList;
  for (const [key] of Object.entries(ElementPlusIconsVue)) {
    iconNameList.push({ value: key });
  }
  return iconNameList;
};

onMounted(async () => {
  getSysMenuInfo();
  getSysApiInfo();
});
</script>

<style lang="scss">
// 覆盖默认 select trigger 样式
.iconselect-trigger .arco-select-dropdown-list {
  display: flex;
  flex-wrap: wrap;
}

.iconselect-trigger .arco-select-option {
  width: auto;
}

// 覆盖默认穿梭框样式
.menu-modal {
  .arco-transfer-view {
    height: 350px;
    width: 250px;
  }
}
</style>
